从 fesacr 源码中总结出的 Java 代码编写注意事项
最近在看 fesacr 的源码, 从中也看到有一些代码书写不规范或是有误的地方.本文总结了自己看源码过程中目前发现的一些问题, 都已在 github 上提了 issue 或 pr.
字符串格式化
在 Java API 中一般有两种方式对字符串进行格式化:
String.format()
MessageFormat.format()
以上两种方法的主要差异其实就是要格式化的字符串中的占位符, String.format()
使用类似于 %s
(表示字符)这样的占位符, MessageFormat.format()
使用 {0}
({参数索引}
).
而我们在项目开发中, 都会使用日志框架, 在打印日志的时候, 也会使用占位符进行格式化字符串, 占位符一般为 {}
, 所以在项目开发过程中可能会搞错这几种方式, 搞混了这几种占位符.所以需要格外的注意.
对于 String.format()
而言, IDEA 其实已经提供了较好的验证支持,
相关 issue 可见: https://github.com/alibaba/fescar/issues/122
不要使用 File.rename() 对文件重命名
如果我们想对文件进行重命名, 首先想到的就是使用 File.rename()
方法, 但是仔细看看此方法的说明, 其实这个方法是不靠谱的, 也就是说有可能会失败.
1 | /** |
在几年前, 在用 Jetty 的时候, 也是遇到过这个问题.后来排查原因, 就是因为 File.rename()
引起的.所以最好不要使用此方法重命名.可以使用 Files.move()
或者是 apache commons-io
包中的方法.
相关 issue 可见: https://github.com/alibaba/fescar/issues/92
关闭 io 流的时候避免冗余的 close() 方法调用
有如下一个获取文件 channel 的例子:
1 | File file = new File(...); |
一般我们可以通过上述的方式写入数据到文件中, 在最后关闭的时候, 大部分时候可能是为了保险起见, 会使用如下的代码关闭相关的资源:
1 | fileChannel.close(); |
但是如下仔细查看 RandomAccessFile.close()
方法的源码, 就会发现, 其实这个方法的内部会自动调用 fileChannel.close()
:
1 | public void close() throws IOException { |
从上面可以看出, 关闭文件相关资源的时候, 只需要调用 RandomAccessFile.close()
, 而不需要再调用一次 fileChannel.close()
.
相关 issue 可见: https://github.com/alibaba/fescar/issues/127
Netty 服务端设置 SO_KEEPALIVE 是没有用的
在用 Netty 进行网络编程的时候, 通过会设置 SO_KEEPALIVE
选项为 true
:
1 | this.serverBootstrap.group(this.eventLoopGroupBoss, this.eventLoopGroupWorker) |
初看上面的代码感觉是没有任何问题的, 有可能项目跑起来的时候也注意不到有什么问题.看如果真的细看启动日志就会发现, 使用上面的代码启动后, 会打印如下的警告日志:
1 | WARN io.netty.bootstrap.ServerBootstrap - Unknown channel option 'SO_KEEPALIVE' for channel ... |
这个问题的解决方案也很简单, 应该使用 childOption()
方法.这一点比较难以察觉的, 有时候需要观察下启动日志.
相关 issue 可见: https://github.com/alibaba/fescar/issues/150
- 感谢您的阅读,本文由 ykgarfield 版权所有。如若转载,请注明出处:ykgarfield
- 文章链接: https://ykgarfield.github.io/2019/01/20/Java/代码规范/从 fesacr 源码中总结出的 Java 代码编写注意事项/